home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 February: Tool Chest / Apple Developer CD Series Tool Chest February 1996 (Apple Computer)(1996).iso / Sample Code / AOCE Sample Code / PowerTalk Access Modules / Sample SMSAM / SampleSMSAM Source / BuildingBlocks / DataItem.cp < prev    next >
Encoding:
Text File  |  1995-07-28  |  14.6 KB  |  598 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        DataItem.cp
  3.  
  4.     Copyright:    © 1991-1994 by Apple Computer, Inc.
  5.                 All rights reserved.
  6.  
  7.     Part of the AOCE Sample SMSAM Package.  Consult the license
  8.     which came with this software for your specific legal rights.
  9.  
  10. */
  11.  
  12.  
  13.  
  14. #ifndef __DATAITEM__
  15. #include "DataItem.h"
  16. #endif
  17.  
  18. #ifndef    __DEBUGASSERT__
  19. #include "DebugAssert.h"
  20. #endif
  21.  
  22. #ifndef    __DEBUGCONSTANTS__
  23. #include "DebugConstants.h"
  24. #endif
  25.  
  26. #ifndef __STDIO__
  27. #include <stdio.h>
  28. #endif
  29.  
  30. /***********************************|****************************************/
  31.  
  32. #pragma segment DataItem
  33.  
  34. /***********************************|****************************************/
  35.  
  36.  
  37. inline long Minimum ( long a, long b)
  38. {
  39.     return ( a < b ) ? a : b;
  40. }
  41.  
  42. /***********************************|****************************************/
  43.  
  44. ADataItem::ADataItem ()
  45. {
  46. }
  47.  
  48. /***********************************|****************************************/
  49.  
  50. ADataItem::~ADataItem ()
  51. {
  52. }
  53.  
  54. /***********************************|****************************************/
  55.  
  56. short
  57. CompareDataItems ( const void* aa, unsigned long alen, const void* bb, unsigned long blen )
  58. {
  59.     register short diff = 0;
  60.     unsigned long c = alen < blen ? alen : blen;
  61.     const char* a = (char*) aa;
  62.     const char* b = (char*) bb;
  63.  
  64.     while ( c-- > 0 )
  65.     {
  66.         diff = *a++ - *b++;
  67.  
  68.         if ( diff != 0 )
  69.             break;
  70.     }
  71.  
  72.     if ( diff == 0 )
  73.         diff = (short) ( (long) alen - (long) blen );
  74.  
  75.     return diff;
  76. }
  77.  
  78. /***********************************|****************************************/
  79.  
  80. ADataItem&
  81. ADataItem::operator = ( const ADataItem& that )
  82. {
  83.     if ( this != &that )
  84.     {
  85.         ReadFrom ( that.GetPhysicalStart (), that.GetPhysicalLength (), that.GetDataType() );
  86.     }
  87.     else
  88.     {
  89.         ASSERT ( this != &that );
  90.     }
  91.  
  92.     return *this;
  93. }
  94.  
  95. #if 1
  96. /***********************************|****************************************/
  97.  
  98. ADataItem& ADataItem::operator = ( const long l )
  99. {
  100.     ReadFrom ( &l, sizeof(l), typeLongInteger );
  101.     return *this;
  102. }
  103.  
  104. /***********************************|****************************************/
  105.  
  106. ADataItem& ADataItem::operator = ( const char* str)
  107. {
  108.     unsigned long len = strlen(str) + 1;
  109.     ReadFrom ( str, len, typeChar );
  110.     return *this;
  111. }
  112.  
  113. /***********************************|****************************************/
  114.  
  115. ADataItem& ADataItem::operator = ( const StringPtr str )
  116. {
  117.     ReadFrom ( &str[1], str[0], typeChar );
  118.     return *this;
  119. }
  120.  
  121. /***********************************|****************************************/
  122.  
  123. ADataItem::operator long () const
  124. {
  125.     if ((GetDataType() == typeInteger) ||
  126.         (GetDataType() == typeLongInteger) ||
  127.         (GetDataType() == typeShortInteger) ||
  128.         (GetDataType() == typeSMInt) ||
  129.         (GetDataType() == typeLongInteger))
  130.         return * (long *) GetPhysicalStart();
  131.     else if (GetDataType() == typeBoolean)
  132.         return * (Boolean *) GetPhysicalStart();
  133.     else if (GetDataType() == typeChar) {
  134.         long l;
  135.         sscanf ( (char*) GetPhysicalStart(), "%d", & l );
  136.         return l;
  137.     } else {
  138.         ASSERT ( false );
  139.         return 0;
  140.     }
  141. }
  142.  
  143. /***********************************|****************************************/
  144.  
  145. ADataItem::operator Str255& () const
  146. {    static    Str255 str;
  147.     
  148.     str[0] = 0;
  149.     if (GetDataType() == typeChar)
  150.     {
  151.         str[0] = (unsigned char) GetPhysicalLength();
  152.         WriteTo ( &str[1], str[0] );
  153.     } else if ((GetPhysicalLength() >= sizeof(long)) &&
  154.         ((GetDataType() == typeInteger) ||
  155.         (GetDataType() == typeLongInteger) ||
  156.         (GetDataType() == typeShortInteger) ||
  157.         (GetDataType() == typeSMInt) ||
  158.         (GetDataType() == typeLongInteger)))
  159.     {
  160.         str[0] = (unsigned char) sprintf ( (char*) &str[1], "%d", * (long *) GetPhysicalStart());
  161.     } else {
  162.         ASSERT ( false );
  163.         str [ 0 ] = 0;
  164.     }
  165.     
  166.     return str;
  167. }
  168.  
  169. #endif
  170.  
  171. /***********************************|****************************************/
  172.  
  173. unsigned long
  174. ADataItem::ReadFrom ( const void* source, unsigned long sourceLength, DescType dataType )
  175. {
  176.     unsigned long newLength = SetPhysicalLength ( sourceLength );
  177.     ASSERT ( newLength >= sourceLength );
  178.     unsigned long copiedLength = Minimum ( newLength, sourceLength );
  179.     BlockMove ( source, (void*) GetPhysicalStart (), copiedLength );
  180.     SetDataType ( dataType );
  181.     return copiedLength;
  182. }
  183.  
  184. /***********************************|****************************************/
  185.  
  186. unsigned long
  187. ADataItem::WriteTo ( void* dest, unsigned long destLength ) const
  188. {
  189.     unsigned long desiredLength = GetPhysicalLength ();
  190.     ASSERT ( destLength >= desiredLength );
  191.     unsigned long copiedLength = Minimum ( destLength, desiredLength );
  192.     BlockMove ( GetPhysicalStart (), dest, copiedLength );
  193.     return copiedLength;
  194. }
  195.  
  196. /***********************************|****************************************/
  197.  
  198. Boolean
  199. ADataItem::operator == ( const ADataItem& that ) const
  200. {
  201.     if (that.GetDataType() == GetDataType())
  202.         return 0 == ::CompareDataItems ( GetPhysicalStart (), GetPhysicalLength (), that.GetPhysicalStart (), that.GetPhysicalLength () );
  203.     else
  204.         return false;
  205. }
  206.  
  207. /***********************************|****************************************/
  208.  
  209. void
  210. ADataItem::FillDataItem ( unsigned char c )
  211. {
  212.     unsigned char* p = (unsigned char*) GetPhysicalStart ();
  213.     unsigned long length = GetPhysicalLength ();
  214.  
  215.     while ( length-- > 0 )
  216.         *p++ = c;
  217. }
  218.  
  219. /***********************************|****************************************/
  220.  
  221. #ifndef    __FSTREAM__
  222. #include "FStream.h"
  223. #endif
  224.  
  225. extern ostream& DumpHex (ostream& s, const void *p, unsigned long size);
  226.  
  227. ostream&
  228. ADataItem::operator >> ( ostream& stream ) const
  229. {
  230.     if ( chrisFlag.Flag ( kExtensiveBufferDescribe ) )
  231.     {
  232.         stream << "ADataItem @ " << (void*) this << "\n";
  233.         DescType type = GetDataType();
  234.         stream << "\tGetDataType(): "; stream.write ( (char*) &type, sizeof(type)); stream << "\n";
  235.         stream << "\tGetPhysicalLength (): " << GetPhysicalLength () << "\n";
  236.         stream << "\tGetPhysicalStart (): ";
  237.         DumpHex ( stream, (char*) GetPhysicalStart (), GetPhysicalLength () );
  238.     }
  239.     else
  240.     {
  241.         switch ( GetDataType () )
  242.         {
  243.             case typeChar:
  244.                 stream << "'";
  245.                 stream.write ( (char*) GetPhysicalStart (), GetPhysicalLength () );
  246.                 stream << "'";
  247.                 break;
  248.             
  249.             case typeBoolean:
  250.                 if ( * (Boolean *) GetPhysicalStart () )
  251.                     stream << "true ";
  252.                 else
  253.                     stream << "false ";
  254.                 break;
  255.                 
  256.             case typeInteger:
  257.                 stream << * ( long *) GetPhysicalStart ();
  258.                 break;
  259.             
  260.             case typeSMInt:
  261.                 stream << * ( short *) GetPhysicalStart ();
  262.                 break;
  263.             
  264.             case typeTrue:
  265.                 stream << "TRUE ";
  266.                 break;
  267.             
  268.             case typeFalse:
  269.                 stream << "FALSE ";
  270.                 break;
  271.                 
  272.             default:
  273.                 stream << "dataType:"; OutputOSType ( stream, GetDataType () ); stream << " ";
  274.                 stream << GetPhysicalLength () << " bytes @ " << (void*) GetPhysicalStart () << '\n';
  275.                 break;
  276.         }
  277.     }
  278.  
  279.     return stream;
  280. }
  281.  
  282. /***********************************|****************************************/
  283. /***********************************|****************************************/
  284.  
  285. CDataItem::CDataItem ():
  286.     ADataItem (),
  287.     fIsExternal ( false ),
  288.     fDataType( typeWildCard )
  289. {
  290.     SetPhysicalLength ( sizeof ( unsigned long ) );
  291. }
  292.  
  293. /***********************************|****************************************/
  294.  
  295. CDataItem::CDataItem ( unsigned long length, DescType dataType ):
  296.     ADataItem (),
  297.     fIsExternal ( false ),
  298.     fDataType ( dataType )
  299. {
  300.     SetPhysicalLength ( length );
  301. }
  302.  
  303. /***********************************|****************************************/
  304.  
  305. CDataItem::CDataItem ( const void* source, unsigned long sourceLength, DescType dataType ):
  306.     ADataItem (),
  307.     fIsExternal ( false ),
  308.     fDataType ( dataType )
  309. {
  310.     SetPhysicalLength ( sourceLength );
  311.     BlockMove ( (Ptr) source, (Ptr) GetPhysicalStart (), GetPhysicalLength () );
  312. }
  313.  
  314. /***********************************|****************************************/
  315.  
  316. CDataItem::CDataItem ( const ADataItem& that ):
  317.     ADataItem (),
  318.     fIsExternal ( false )
  319. {
  320.     SetDataType ( that.GetDataType() );
  321.     SetPhysicalLength ( that.GetPhysicalLength () );
  322.     BlockMove ( (Ptr) that.GetPhysicalStart (), (Ptr) GetPhysicalStart (),  (Size) GetPhysicalLength () );
  323. }
  324.  
  325. /***********************************|****************************************/
  326.  
  327. CDataItem::CDataItem ( const CDataItem& that ):
  328.     ADataItem (),
  329.     fIsExternal ( false )
  330. {
  331.     SetDataType ( that.GetDataType() );
  332.     SetPhysicalLength ( that.GetPhysicalLength () );
  333.     BlockMove ( (Ptr) that.GetPhysicalStart (),(Ptr)  GetPhysicalStart (),( Size)  GetPhysicalLength () );
  334. }
  335.  
  336. /***********************************|****************************************/
  337.  
  338. CDataItem&
  339. CDataItem::operator = ( const CDataItem& that )
  340. {
  341.     if ( this != &that )
  342.     {
  343.         SetDataType ( that.GetDataType() );
  344.         ReadFrom ( that.GetPhysicalStart (), that.GetPhysicalLength (), that.GetDataType() );
  345.     }
  346.     else
  347.     {
  348.         ASSERT ( this != &that );
  349.     }
  350.  
  351.     return *this;
  352. }
  353.  
  354. /***********************************|****************************************/
  355.  
  356. CDataItem::~CDataItem ()
  357. {
  358.     if ( fIsExternal )
  359.         DeallocatePtr( (Ptr) fType.fExternal.fDataItem );
  360. }
  361.  
  362. /***********************************|****************************************/
  363.  
  364. unsigned long
  365. CDataItem::SetPhysicalLength ( unsigned long length )
  366. {
  367.     if ( fIsExternal )
  368.         DeallocatePtr( (Ptr) fType.fExternal.fDataItem );
  369.     
  370.     if ( length < 0 )
  371.     {
  372.         fIsExternal = false;
  373.         fType.fInternal.fLength = 0;
  374.         return fType.fInternal.fLength;
  375.     }
  376.     else if ( length > kDataItemMaxInternalLength )
  377.     {
  378.         fType.fExternal.fDataItem = FAILNewPtrClear ( length );
  379.         if ( fType.fExternal.fDataItem )
  380.         {
  381.             fIsExternal = true;
  382.             return fType.fExternal.fLength = length;
  383.         }
  384.         else
  385.         {
  386.             ASSERT(noErr == MemError ());
  387.             fIsExternal = false;
  388.             return fType.fInternal.fLength = kDataItemMaxInternalLength;
  389.         }
  390.     }
  391.     else
  392.     {
  393.         fIsExternal = false;
  394.         return fType.fInternal.fLength = length;
  395.         return length;
  396.     }
  397. }
  398.  
  399. /***********************************|****************************************/
  400.  
  401. ostream&
  402. CDataItem::operator >> ( ostream& s ) const
  403. {
  404.     ADataItem::operator >> ( s );
  405.  
  406. #if debug
  407.     if ( chrisFlag.Flag ( kExtensiveBufferDescribe ) )
  408.     {
  409.         s << "\tfIsExternal: " << (short) fIsExternal << '\n';
  410.  
  411.         if ( fIsExternal )
  412.         {
  413.             s << "\tfLength: " << fType.fExternal.fLength << '\n';
  414.             s << "\tfDataItem: " << fType.fExternal.fDataItem;
  415.         }
  416.         else
  417.         {
  418.             s << "\tfLength: " << (short) fType.fInternal.fLength;
  419. //             s << "\tfDataItem: " << fType.fInternal.fDataItem;
  420.         }
  421.     }
  422. #endif
  423.  
  424.     return s;
  425. }
  426.  
  427. /***********************************|****************************************/
  428. /***********************************|****************************************/
  429.  
  430. CPrefixDataItem::CPrefixDataItem ( DataItemPrefix prefix, unsigned long logicalLength ):
  431.     ADataItem (),
  432.     fDataItem ( logicalLength + prefix ),
  433.     fSource ( nil ),
  434.     fPrefix ( prefix ),
  435.     fUpdate ( false )
  436. {
  437.     UpdatePrefixWithLength ( 0 );
  438. }
  439.  
  440. /***********************************|****************************************/
  441.  
  442. CPrefixDataItem::CPrefixDataItem ( const ADataItem& source, DataItemPrefix prefix ):
  443.     ADataItem (),
  444.     fDataItem ( (const char*) source.GetPhysicalStart () - prefix, source.GetPhysicalLength () + prefix ),
  445.     fSource ( (ADataItem*) &source ),
  446.     fPrefix ( prefix ),
  447.     fUpdate ( false )
  448. {
  449.     UpdatePrefixWithLength ( source.GetPhysicalLength () );
  450. }
  451.  
  452. /***********************************|****************************************/
  453.  
  454. CPrefixDataItem::CPrefixDataItem ( ADataItem& source, Boolean update, DataItemPrefix prefix ):
  455.     ADataItem (),
  456.     fDataItem ( (const char*) source.GetPhysicalStart () - prefix, source.GetPhysicalLength () + prefix ),
  457.     fSource ( &source ),
  458.     fPrefix ( prefix ),
  459.     fUpdate ( update )
  460. {
  461.     UpdatePrefixWithLength ( source.GetPhysicalLength () );
  462. }
  463.  
  464. /***********************************|****************************************/
  465.  
  466. CPrefixDataItem::CPrefixDataItem ( const void* source, unsigned long length, DataItemPrefix prefix ):
  467.     ADataItem (),
  468.     fDataItem ( (char*) source - prefix, length + prefix ),
  469.     fSource ( nil ),
  470.     fPrefix ( prefix ),
  471.     fUpdate ( false )
  472. {
  473.     UpdatePrefixWithLength ( length );
  474. }
  475.  
  476. /***********************************|****************************************/
  477.  
  478. void
  479. CPrefixDataItem::UpdatePrefixWithLength ( unsigned long length )
  480. {
  481.     void* start = (void*) fDataItem.GetPhysicalStart ();
  482.  
  483.     switch ( fPrefix )
  484.     {
  485.         case kByte:
  486.             *(unsigned char*) start = (unsigned char) length;
  487.         break;
  488.  
  489.         case kWord:
  490.             *(unsigned short*) start = (unsigned short) length;
  491.         break;
  492.  
  493.         case kLong:
  494.             *(unsigned long*) start = (unsigned long) length;
  495.         break;
  496.     }
  497. }
  498.  
  499. /***********************************|****************************************/
  500.  
  501. unsigned long
  502. CPrefixDataItem::SetLogicalLength ( unsigned long requestedLogicalLength )
  503. {
  504.     unsigned long requestedPhysicalLength = requestedLogicalLength + fPrefix;
  505.     unsigned long actualPhysicalLength = fDataItem.GetPhysicalLength ();
  506.  
  507.     if ( actualPhysicalLength < requestedPhysicalLength )
  508.     {
  509.         actualPhysicalLength = fDataItem.SetPhysicalLength ( requestedPhysicalLength );
  510.         ASSERT_RETURN_ZERO ( actualPhysicalLength >= requestedPhysicalLength );
  511.     }
  512.  
  513.     unsigned long actualLogicalLength = actualPhysicalLength - fPrefix;
  514.     UpdatePrefixWithLength ( actualLogicalLength );
  515.     return actualLogicalLength;
  516. }
  517.  
  518. /***********************************|****************************************/
  519.  
  520. unsigned long
  521. CPrefixDataItem::GetLogicalLength () const
  522. {
  523.     switch ( fPrefix )
  524.     {
  525.         case kByte: return *(unsigned char*) fDataItem.GetPhysicalStart ();
  526.         case kWord: return *(unsigned short*) fDataItem.GetPhysicalStart ();
  527.         case kLong: return *(unsigned long*) fDataItem.GetPhysicalStart ();
  528.     };
  529.     return 0; //in case of error
  530. }
  531.  
  532. /***********************************|****************************************/
  533.  
  534. CPrefixDataItem::~CPrefixDataItem ()
  535. {
  536.     UpdateNow ();
  537. }
  538.  
  539. /***********************************|****************************************/
  540.  
  541. unsigned long
  542. CPrefixDataItem::UpdateNow ()
  543. {
  544.     if ( fUpdate && fSource )
  545.         return fSource->ReadFrom ( GetLogicalStart (), GetLogicalLength (), typeWildCard );
  546.     else
  547.         return 0;
  548. }
  549.  
  550. /***********************************|****************************************/
  551.  
  552. ostream&
  553. CPrefixDataItem::operator >> ( ostream& s ) const
  554. {
  555.     ADataItem::operator >> ( s );
  556.  
  557. #if debug
  558.     if ( chrisFlag.Flag ( kExtensiveBufferDescribe ) )
  559.     {
  560. //         s << "\tfDataItem: " << fDataItem << '\n';
  561.         s << "\tfSource: " << fSource << '\n';
  562.         s << "\tfPrefix: " << (short) fPrefix << '\n';
  563.         s << "\tfUpdate: " << (short) fUpdate;
  564.     }
  565. #endif
  566.  
  567.     return s;
  568. }
  569.  
  570. /***********************************|****************************************/
  571. /***********************************|****************************************/
  572.  
  573. CWrapperDataItem::CWrapperDataItem ( void* source, unsigned long length , DescType dataType ):
  574.     ADataItem (),
  575.     fSource ( source ),
  576.     fLength ( length ),
  577.     fDataType ( dataType )
  578. {
  579. }
  580.  
  581. /***********************************|****************************************/
  582.  
  583. CWrapperDataItem::~CWrapperDataItem ()
  584. {
  585. }
  586.  
  587. /***********************************|****************************************/
  588.  
  589. unsigned long
  590. CWrapperDataItem::SetPhysicalLength ( unsigned long newLength )
  591. {
  592.     ASSERT ( newLength == fLength);
  593.  
  594.     return fLength;
  595. }
  596.  
  597. /***********************************|****************************************/
  598.